/**
 * FileName: ServerHandler
 * Author: Mr.Wang
 * Date: 2025/10/15 15:16
 * Description:
 * History:
 */
package org.test.device.config.netty;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.core.task.TaskExecutor;

/**
 * 〈一句话功能简述〉<br>
 * 〈netty服务端处理器〉
 * 接收信息
 * @author Mr.Wang
 * @create 2025/10/15
 * @since 1.0.0
 */
@Slf4j
public class ServerHandler extends ChannelInboundHandlerAdapter {

    // 任务执行器（用于异步处理业务逻辑）
    @Qualifier("nettyInitTaskExecutor")
    private final TaskExecutor primaryTaskExecutor;

    // JSON解析器（用于解析客户端消息中的messageId，构建JSON响应）
    private static final ObjectMapper objectMapper = new ObjectMapper();

    // 构造函数，接收任务执行器
    public ServerHandler(TaskExecutor primaryTaskExecutor) {
        this.primaryTaskExecutor = primaryTaskExecutor;
    }

    // 客户端连接
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        log.info("[ServerHandler]客户端连接：{}", ctx.channel().remoteAddress());
    }

    // 客户端断开连接时触发-log
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        log.info("[ServerHandler]客户端[{}]已断开连接", ctx.channel().remoteAddress());
    }

    // 收到客户端消息时调用
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        String clientMsg = (String) msg;

        //过滤心跳消息
        if ("HEARTBEAT".equals(clientMsg)) {
            ctx.writeAndFlush("PONG"); // 回复心跳确认
            return;
        }

        //消息大小校验
        if (clientMsg.length() > 10240) { // 限制10KB
            log.warn("[ServerHandler]客户端[{}]发送超大消息（长度：{}），已拒绝",
                    ctx.channel().remoteAddress(), clientMsg.length());
            ctx.writeAndFlush("消息过长（最大10KB），拒绝处理");
            return;
        }

        //异步处理业务逻辑（避免阻塞I/O线程）
        primaryTaskExecutor.execute(() -> {
            try {
                // 模拟耗时业务处理（如数据库操作、复杂计算）
                log.info("[ServerHandler]开始处理客户端[{}]消息：{}", ctx.channel().remoteAddress(), clientMsg);
                Thread.sleep(100); // 模拟耗时

                //解析客户端消息，提取messageId（核心步骤）
                String messageId = "UNKNOWN"; // 默认值，防止解析失败
                JsonNode clientJson = objectMapper.readTree(clientMsg);
                if (clientJson.has("messageId")) {
                    messageId = clientJson.get("messageId").asText();
                }
                //构建标准 JSON 回复（顶层含 messageId，与客户端期望格式匹配）
                ObjectNode replyJson = objectMapper.createObjectNode();
                replyJson.put("messageId", messageId); // 顶层messageId，客户端用于匹配回调
                replyJson.put("result", "已收到并处理消息"); // 处理结果
                replyJson.set("content", clientJson.get("content")); // 带回客户端原始业务数据
                String replyMsg = objectMapper.writeValueAsString(replyJson);

                //通过I/O线程发送回复
                ctx.channel().eventLoop().execute(() -> ctx.writeAndFlush(replyMsg));
            } catch (Exception e) {
                log.error("[ServerHandler]处理客户端[{}]消息异常", ctx.channel().remoteAddress(), e);
                ctx.channel().eventLoop().execute(() -> ctx.writeAndFlush("处理消息失败：" + e.getMessage()));
            }
        });
    }

    // 消息读取完成后触发
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) {
        log.info("[ServerHandler]消息读取完成，准备发送...........");
        ctx.flush(); // 确保数据立即发送
    }

    // 3. 处理异常
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        log.error("[ServerHandler]服务器处理客户端[{}]消息异常", ctx.channel().remoteAddress(), cause);
        ctx.close();
    }
}